<?php
class Queue
{
    const DIR_QUEUE = '/../queue/';
    const DIR_COMMON = '/../queue/common/';
    const DIR_UNSENT = '/../queue/unsent/';

    private static $instance = false;
    private $dirCommon = false;
    private $dirUnsent = false;

    private function __construct()
    {
        $this->dirQueue = dirname(__FILE__) . self::DIR_QUEUE;
        $this->dirCommon = dirname(__FILE__) . self::DIR_COMMON;
        $this->dirUnsent = dirname(__FILE__) . self::DIR_UNSENT;
    }

    private function __clone()
    {
    }

    private static function getInstance()
    {
        if (self::$instance === false)
        {
            self::$instance = new Queue();
        }

        return self::$instance;
    }

    private static function generateFilename()
    {
        $t = explode('.', microtime(true));

        return str_pad($t[0], 12, '0', STR_PAD_LEFT) . '-' . str_pad($t[1], 5, '0', STR_PAD_RIGHT) . '.msg';
    }

    public static function add($email, $subject, $body)
    {
        $filename = self::generateFilename();

        $content = array(
            'email'     => $email,
            'subject'   => $subject,
            'body'      => $body
        );

        if (file_put_contents(self::getInstance()->dirCommon . $filename, serialize($content)))
        {
            return $filename;
        }

        return false;
    }

    public static function get($workerPid)
    {
        $newFilename = self::getInstance()->dirQueue . $workerPid . '.msg';

        // если осталась незавершенная задача - выполняем ее
        if (file_exists($newFilename))
        {
            return unserialize( file_get_contents($newFilename) );
        }

        $files = scandir(self::getInstance()->dirCommon);

        if (isset($files[2]))
        {
            $oldFilename = self::getInstance()->dirCommon . $files[2];

            if (file_exists($oldFilename) && @rename($oldFilename, $newFilename))
            {
                return unserialize( file_get_contents($newFilename) );
            }
        }

        return false;
    }

    public static function close($workerPid, $isSent)
    {
        $filename = self::getInstance()->dirQueue . $workerPid . '.msg';

        if ($isSent == true)
        {
            return unlink($filename);
        }
        else
        {
            return rename($filename, self::getInstance()->dirUnsent . self::generateFilename());
        }
    }
}
